home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / dbase / kf2ex.lha / KingFisher-Distribution / Developer / CLIent.c < prev    next >
C/C++ Source or Header  |  1994-11-02  |  15KB  |  509 lines

  1. /****************************************************************************
  2. * KingFisher Release 2 CLI client: "CLIent"
  3. * Copyright © 1994 by Udo Schuermann
  4. * All rights reserved
  5. * ------------------------------------------------------------------------
  6. * Demonstration of a KingFisher Release 2 message-based interface without the
  7. * use of the kf-api.  In other words, we do everything the "hard" way here.
  8. * ------------------------------------------------------------------------
  9. * This program is available only to registered users of KingFisher.
  10. * PLEASE DO NOT REDISTRIBUTE!
  11. ****************************************************************************/
  12.  
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17.  
  18. #include <exec/memory.h>
  19. #include <libraries/dos.h>
  20. #include <proto/exec.h>
  21. #include <proto/dos.h>
  22.  
  23. #include "kf.h"
  24. #include "kf-err.c"      /* defines KFError[] array */
  25.  
  26.  
  27. #define VERSION "1.4"
  28.  
  29. /* prototypes */
  30. BOOL TellKF( struct KFMsg *myMsg );
  31.  
  32. #ifndef __MYDATE__
  33. #define __MYDATE__ __AMIGADATE__
  34. #endif
  35.  
  36. char Version[] = "$VER: CLIent "VERSION" for KingFisher Release 2 "__MYDATE__;
  37.  
  38.  
  39.  
  40. void UpgradeBuffer( struct KFMsg *myMsg ) {
  41.   char *p;
  42.  
  43.   /* Is the maximum required/requested buffer size (myMsg->BParam) larger than what
  44.    * we have currently allocated (myMsg->BufferSize)? */
  45.   if( myMsg->BParam > myMsg->BufferSize ) {
  46.     /* then try reallocating the memory to which we are pointing... */
  47.     if( p = realloc(myMsg->Buffer,myMsg->BParam) ) {
  48.       printf("NOTE: Upgraded our buffer from %d to %d bytes in size\n",
  49.          myMsg->BufferSize,myMsg->BParam);
  50.       myMsg->BufferSize = myMsg->BParam;
  51.       myMsg->Buffer = p;
  52.     } else
  53.       printf("Could not upgrade our buffer from %d to %d bytes\n",
  54.          myMsg->BufferSize,myMsg->BParam);
  55.   }
  56. } /* UpgradeBuffer() */
  57.  
  58.  
  59.  
  60. void main() {
  61.  
  62.   struct MsgPort *myPort=NULL;
  63.   struct KFMsg *myMsg,*reply;
  64.   BOOL happy = TRUE,connected=FALSE;
  65.   char cmd[80];
  66.   char *p,*q;
  67.   LONG n,i;
  68.  
  69.   printf("CLIent "VERSION" for KingFisher Release 2\n"
  70.      "Copyright \© 1994 by Udo Schuermann\n"
  71.      "All rights reserved\n\n");
  72.  
  73.  
  74.   if( FindPort( KFPortName ) ) {
  75.  
  76.     /*****************************************************************
  77.      * Initialize our message; we use this one to communicate with the
  78.      * KFServer's message port.  If something fails, we'll just set
  79.      * the variable 'happy' to FALSE to avoid running through the main
  80.      * while() loop below.
  81.      *****************************************************************
  82.      */
  83.     if( myMsg = AllocMem( sizeof(struct KFMsg), MEMF_PUBLIC|MEMF_CLEAR ) ) {
  84.       myMsg->AmigaMsg.mn_Node.ln_Type = NT_MESSAGE;
  85.       myMsg->AmigaMsg.mn_Length       = sizeof(struct KFMsg);
  86.       if( myMsg->AmigaMsg.mn_ReplyPort = myPort = CreateMsgPort() ) {
  87.     if( myMsg->Buffer = malloc( 256 ) )
  88.       myMsg->BufferSize = 256;
  89.     else {
  90.       printf("Cannot allocate 256 bytes for buffer space!\n");
  91.       happy = FALSE;
  92.     }
  93.       } else {
  94.     printf("Cannot create a private message port!\n");
  95.     happy = FALSE;
  96.       }
  97.     } else {
  98.       printf("Cannot allocate memory for message interface!\n");
  99.       happy = FALSE;
  100.     } /* if */
  101.  
  102.  
  103.     /*****************************************************************
  104.      * Now loop until we're no longer "happy," i.e. made to shut down
  105.      * or the user decided to shut us down.
  106.      *****************************************************************
  107.      */
  108.     while( happy ) {
  109.       /*****************************************************************
  110.        * Prompt the user for input and process it
  111.        *****************************************************************
  112.        */
  113.       printf("\nKF Ready: ");
  114.       fflush(stdout);
  115.       if( p = fgets(cmd,sizeof(cmd),stdin) ) {
  116.     /* convert string "foo bar fun" to "foo\0bar fun" where p points to "bar fun" */
  117.     while( *p > ' ' )
  118.       p++;
  119.     if( *p )
  120.       *p++ = '\0';
  121.     while( *p == ' ' )
  122.       p++;
  123.     /* kill the terminating newline, too */
  124.     q = p;
  125.     while( *q )
  126.       if( *q == '\n' )
  127.         *q = '\0';
  128.       else
  129.         q++;
  130.  
  131.     /*****************************************************************
  132.      * we now have converted a line such as
  133.      *      get=4289\n\0
  134.      *      ^cmd
  135.      * to this:
  136.      *      get\04289\0
  137.      *      ^cmd ^p
  138.      *****************************************************************
  139.      */
  140.  
  141.  
  142.     /*****************************************************************
  143.      * HELP
  144.      *****************************************************************
  145.      */
  146.     if( (stricmp(cmd,"?") == 0) || (stricmp(cmd,"help") == 0) )
  147.       printf("The CLIent understands the following commands:\n"
  148.          "  ? or HELP     This display\n"
  149.          "  HELLO [name]  Announce yourself to the server (optional name)\n"
  150.          "  BYE           Say good-bye to the server\n"
  151.          "  STATUS        Get status information\n"
  152.          "  GET [n]       Get fish n (n is optional fish number)\n"
  153.          "  POS           Get current position in database\n"
  154.          "  TEST n        Retrieve n successive fish\n"
  155.          "  LIST          List all databases available for use\n"
  156.          "  USE database  Select a new database for use\n"
  157.          "  BUILD file    Add all fish from given file, unconditionally\n"
  158.          "  PARSE file    Add fish from given file with prompts for each\n"
  159.          "  REINDEX       Reindexes the current database\n"
  160.          "  QUIT          Quit the CLIent\n");
  161.     else
  162.  
  163.     /*****************************************************************
  164.      * HELLO
  165.      *****************************************************************
  166.      */
  167.     if( stricmp(cmd,"HELLO") == 0 ) {
  168.       if( !connected ) {
  169.         myMsg->Command = kfcHELLO;
  170.         myMsg->BParam = (ULONG)FindTask(NULL);
  171.         myMsg->RESERVED = NULL;
  172.         if( myMsg->Buffer ) {
  173.           if( *p == '\0' )
  174.         p = "CLIent "VERSION" for KingFisher Release 2";
  175.           printf("We call ourselves \"%s\"\n",p);
  176.           strncpy(myMsg->Buffer,p,myMsg->BufferSize);
  177.         }
  178.         if( TellKF(myMsg) ) {
  179.           if( myMsg->Error == kfeOK ) {
  180.         printf("You are now connected to the KFServer.\n");
  181.         connected = TRUE;
  182.         UpgradeBuffer( myMsg );
  183.           }
  184.         } if( myMsg->Error != kfeREFUSED )
  185.           connected = TRUE;
  186.       } else
  187.         printf("Use BYE before saying HELLO again.\n");
  188.     } else
  189.  
  190.     /*****************************************************************
  191.      * BYE
  192.      *****************************************************************
  193.      */
  194.     if( stricmp(cmd,"BYE") == 0 ) {
  195.       myMsg->Command = kfcBYE;
  196.       if( TellKF(myMsg) ) {
  197.         if( myMsg->Error == kfeOK ) {
  198.           printf("KFServer has said good bye.\n"
  199.              "Use the HELLO command to reconnect to the KFServer.\n");
  200.           connected = FALSE;
  201.         }
  202.       }
  203.     } else
  204.  
  205.     /*****************************************************************
  206.      * STATUS
  207.      *****************************************************************
  208.      */
  209.     if( stricmp(cmd,"STATUS") == 0 ) {
  210.       myMsg->Command = kfcSTATUS;
  211.       if( TellKF(myMsg) ) {
  212.         if( myMsg->Error == kfeOK )
  213.           printf(myMsg->Buffer);
  214.       }
  215.     } else
  216.  
  217.     /*****************************************************************
  218.      * GET
  219.      *****************************************************************
  220.      */
  221.     if( stricmp(cmd,"GET") == 0 ) {
  222.       myMsg->BParam = atol( p );    /* if 0 then KFServer gets current fish */
  223.       myMsg->Command = kfcGETFISH;
  224.       if( TellKF(myMsg) ) {
  225.         if( myMsg->Error == kfeOK )
  226.           printf("Flags = %04X, Name = ",myMsg->FParam);
  227.           printf(myMsg->Buffer);
  228.       }
  229.     } else
  230.  
  231.     /*****************************************************************
  232.      * POS
  233.      *****************************************************************
  234.      */
  235.     if( stricmp(cmd,"POS") == 0 ) {
  236.       myMsg->Command = kfcGETPOS;
  237.       if( TellKF(myMsg) )
  238.         if( myMsg->Error == kfeOK )
  239.           printf("Current position in database: %d\n",myMsg->BParam);
  240.     } else
  241.  
  242.     /*****************************************************************
  243.      * TEST
  244.      *****************************************************************
  245.      */
  246.     if( stricmp(cmd,"TEST") == 0 ) {
  247.       n = atol(p);
  248.       printf("Retrieving %d successive fish for TEST ...",n);
  249.       myMsg->Command = kfcGETPOS;
  250.       if( TellKF(myMsg) )
  251.         i = myMsg->BParam;
  252.       else
  253.         n = 0;
  254.       while( n > 0 ) {
  255.         myMsg->BParam = i;
  256.         myMsg->Command = kfcGETFISH;
  257.         if( TellKF(myMsg) ) {
  258.           i++;
  259.           n--;
  260.         } else {
  261.           printf(" (test loop terminated by GETFISH %d error)",i);
  262.           n = 0;
  263.         }
  264.       } /* while */
  265.       printf(" done!\n");
  266.     } else
  267.  
  268.     /*****************************************************************
  269.      * LIST
  270.      */
  271.     if( stricmp(cmd,"LIST") == 0 ) {
  272.       myMsg->Command = kfcLISTDBASES;
  273.       if( TellKF(myMsg) )
  274.         printf("---Databases Available---\n%s"
  275.            "-------------------------",myMsg->Buffer);
  276.     } else
  277.  
  278.     /*****************************************************************
  279.      * USE database
  280.      */
  281.     if( stricmp(cmd,"USE") == 0 ) {
  282.       if( *p ) {
  283.         myMsg->Command = kfcSELECTDBASE;
  284.         myMsg->BParam = (ULONG)p;
  285.         if( TellKF(myMsg) ) {
  286.           printf("Database \"%s\" is now in use!",p);
  287.           UpgradeBuffer( myMsg );
  288.         }
  289.       } else
  290.         printf("You should also give the name of a database to use!\n");
  291.     } else
  292.  
  293.     /*****************************************************************
  294.      * PARSE file
  295.      */
  296.     if( stricmp(cmd,"PARSE") == 0 ) {
  297.       if( *p ) {
  298.         myMsg->Command = kfcPARSEFILE;
  299.         myMsg->BParam = (ULONG)p;
  300.         while( TellKF(myMsg) ) {
  301.           if( myMsg->Error == kfeOK ) {
  302.         printf("Disk %d, Flags %04d\n"
  303.                "--------------------NEW FISH--------------------\n%s"
  304.                "------------------------------------------------\n"
  305.                "Add this to the database? (y/N/q) ",1,0,myMsg->Buffer);
  306.         fflush(stdout);
  307.         if( p = fgets(cmd,sizeof(cmd),stdin) ) {
  308.           if( (*p == 'y') || (*p == 'Y') ) {
  309.             myMsg->Command = kfcADDFISH;
  310.             myMsg->BParam  = 1;
  311.             myMsg->FParam  = 0x0000;
  312.             if( TellKF(myMsg) )
  313.               printf("Fish has been added as number %d\n\n",myMsg->BParam);
  314.           } else
  315.             if( (cmd[0] == 'q') || (cmd[0] == 'Q') )
  316.               break;
  317.         } else
  318.           break;
  319.         myMsg->Command = kfcPARSEFILE;  /* prepare for next swing through loop */
  320.           } else
  321.         break;
  322.         } /* while */
  323.         if( myMsg->Error != kfeNOMORE ) {
  324.           myMsg->Command = kfcSTOPPARSE;
  325.           if( TellKF(myMsg) )
  326.         printf("Database has been made sharable again.\n");
  327.         } else
  328.           printf("Parsing completed.  Database is sharable again.\n");
  329.       } else
  330.         printf("Please also give the name of a file!\n");
  331.     } else
  332.  
  333.     /*****************************************************************
  334.      * BUILD file
  335.      */
  336.     if( stricmp(cmd,"BUILD") == 0 ) {
  337.       if( *p ) {
  338.         myMsg->Command = kfcPARSEFILE;
  339.         myMsg->BParam = (ULONG)p;
  340.         while( TellKF(myMsg) ) {
  341.           if( myMsg->Error == kfeOK ) {
  342.         myMsg->Command = kfcADDFISH;
  343.         myMsg->BParam  = 1;
  344.         myMsg->FParam  = 0x0000;
  345.         if( TellKF(myMsg) )
  346.           myMsg->Command = kfcPARSEFILE;  /* prepare for next swing through loop */
  347.         else
  348.           break;
  349.           } else
  350.         break;
  351.         } /* while */
  352.         if( myMsg->Error != kfeNOMORE ) {
  353.           myMsg->Command = kfcSTOPPARSE;
  354.           if( TellKF(myMsg) )
  355.         printf("Database has been made sharable again.\n");
  356.         } else
  357.           printf("Parsing completed.  Database is sharable again.\n");
  358.       } else
  359.         printf("Please also give the name of a file!\n");
  360.     } else
  361.  
  362.     /*****************************************************************
  363.      * REINDEX
  364.      *****************************************************************
  365.      */
  366.     if( stricmp(cmd,"REINDEX") == 0 ) {
  367.       printf("Reindexing ");
  368.       /* we need to loop repeatedly until KFServer tells us it's done
  369.        */
  370.       for(;;) {
  371.         printf(".");
  372.         fflush(stdout);
  373.         myMsg->Command = kfcREINDEX;
  374.         if( !TellKF(myMsg) )
  375.           break;
  376.       } /* for */
  377.       printf("\n");
  378.     } else
  379.  
  380.     /*****************************************************************
  381.      * QUIT (implies a BYE if connected)
  382.      *****************************************************************
  383.      */
  384.     if( stricmp(cmd,"QUIT") == 0 ) {
  385.       if( connected ) {
  386.         myMsg->Command = kfcBYE;
  387.         if( TellKF(myMsg) ) {
  388.           if( myMsg->Error == kfeOK ) {
  389.         printf("KFServer has said good bye.\n");
  390.         connected = FALSE;
  391.           }
  392.         }
  393.       }
  394.       happy = FALSE;
  395.     } else
  396.  
  397.     /*****************************************************************
  398.      * Command not recognized ...
  399.      *****************************************************************
  400.      */
  401.       if( cmd[0] )
  402.         printf("No such command: \"%s\"\n",cmd);
  403.       } else {
  404.     if( connected ) {
  405.       myMsg->Command = kfcBYE;
  406.       if( TellKF(myMsg) ) {
  407.         if( myMsg->Error == kfeOK ) {
  408.           printf("KFServer has said good bye.\n");
  409.           connected = FALSE;
  410.         }
  411.       }
  412.     }
  413.     happy = FALSE;  /* EOF received */
  414.       }
  415.  
  416.       while( reply = (struct KFMsg *)GetMsg( myPort ) ) {
  417.     if( reply->Command == kfcEXIT ) {
  418.       printf("Received EXIT request from server!\n");
  419.       connected = FALSE;
  420.     }
  421.     if( reply != myMsg )
  422.       ReplyMsg( (struct Message *)reply );
  423.       }
  424.     } /* while */
  425.  
  426.     if( myPort )
  427.       DeleteMsgPort( myPort );
  428.  
  429.     if( myMsg ) {
  430.       if( myMsg->Buffer )
  431.     free( myMsg->Buffer );
  432.       FreeMem( myMsg, sizeof(struct KFMsg) );
  433.     }
  434.     printf("Bye-bye!\n");
  435.   } else
  436.     printf("KFServer is not running!\n"
  437.        "Please start the server first!\n");
  438. } /* main */
  439.  
  440.  
  441. /* sends message to KFServer and waits for a reply; waits until our
  442.  * message is returned from server; processes all intermittend
  443.  * stuff from the server (i.e. kfcEXIT requests);
  444.  * returns FALSE if any problem occurred, or if the server asked us
  445.  * to exit; TRUE means "all is well, let's keep on dancing!"
  446.  */
  447. BOOL TellKF( struct KFMsg *myMsg ) {
  448.  
  449.   struct MsgPort *PrimaryPort,*myPort=myMsg->AmigaMsg.mn_ReplyPort;
  450.   struct KFMsg *reply;
  451.   BOOL result=TRUE,showError=TRUE,done=FALSE;
  452.   ULONG sigs;
  453.  
  454.   Forbid();
  455.   if( PrimaryPort = FindPort( KFPortName ) )
  456.     PutMsg( PrimaryPort, (struct Message *)myMsg );
  457.   Permit();
  458.  
  459.   if( PrimaryPort ) {  
  460.     while( !done ) {
  461.       sigs = Wait( (1L << myPort->mp_SigBit) | SIGBREAKF_CTRL_C );
  462.       if( sigs & (1L << myPort->mp_SigBit) )
  463.     while( reply = (struct KFMsg *)GetMsg( myPort ) ) {
  464.       if( reply == myMsg ) {
  465.         done = TRUE;
  466.         if( showError && (myMsg->Error != kfeOK) ) {
  467.           printf("ERROR: %s\n",KFError[myMsg->Error]);
  468.           if( myMsg->Error == kfeTRUNC )
  469.         UpgradeBuffer(myMsg);
  470.           if( myMsg->Buffer )
  471.         printf(myMsg->Buffer);
  472.           printf("\n");
  473.           result = FALSE;
  474.         }
  475.       } else {
  476.         if( reply->Command == kfcEXIT ) {
  477.           printf("Received EXIT request from server!\n");
  478.           result = FALSE;
  479.         } else {
  480.           if( myMsg->Error != kfeOK ) {
  481.         printf("ERROR: %s\n",KFError[myMsg->Error]);
  482.         if( myMsg->Buffer )
  483.           printf(myMsg->Buffer);
  484.         printf("\n");
  485.         showError = FALSE;
  486.         result = FALSE;
  487.           }
  488.         }
  489.         printf("Replying to %08x\n",reply->AmigaMsg.mn_ReplyPort);
  490.         ReplyMsg( (struct Message *)reply );
  491.       }
  492.     } /* while */
  493.       if( sigs & SIGBREAKF_CTRL_C ) {
  494.     SetSignal(0L,SIGBREAKF_CTRL_C);
  495.     printf("Wait for reply from server interrupted.\n"
  496.            "The client is now in a precarious state and should NOT quit!\n");
  497.     done = TRUE;
  498.     result = FALSE;
  499.       }
  500.     } /* while */
  501.   } else {
  502.     printf("The KFServer (%s) has shutdown!\n"
  503.        "Please QUIT the CLIent, too.\n",KFPortName);
  504.     myMsg->Error = 0xffff;
  505.     result = FALSE;
  506.   }
  507.   return result;
  508. } /* Tell */
  509.